﻿using NewLife;
using Yitter.IdGenerator;

namespace Admin.NET.Application.Service;

/// <summary>
/// 血液入库单
/// </summary>
public class InvRuKuService : BaseServiceBill<InvRuKu>
{
    private readonly SqlSugarRepository<InvRuKuMingXi> _repMingXi; //入库明细
    private readonly KuCunManager _managerKuCun; // 库存表
    private readonly SqlSugarRepository<BasXueYeChanPin> _basXueYeChanPin;

    public InvRuKuService(IServiceScopeFactory scopeFactory, SqlSugarRepository<InvRuKuMingXi> repMingXi, KuCunManager managerKuCun, SqlSugarRepository<BasXueYeChanPin> basXueYeChanPin)
        : base(scopeFactory)
    {
        _repMingXi = repMingXi;
        _managerKuCun = managerKuCun;
        _basXueYeChanPin = basXueYeChanPin;
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<SqlSugarPagedList<InvRuKuOutput>> Page(InvRuKuPageInput input)
    {
        var invKuCunList = await Queryable.FuzzyQuery(input.Keyword, new List<string> { "Id" })
           .WhereIF(!input.danJuLeiXing.IsNullOrWhiteSpace(), t => t.danJuLeiXing == input.danJuLeiXing)
           .Select<InvRuKuOutput>()
           .OrderByDescending(it => it.Id)
           .ToPagedListAsync(input.Page, input.PageSize);

        return invKuCunList;
    }

    /// <summary>
    /// 通过Id获取
    /// </summary>
    public async Task<InvRuKuWithMingXiOutput> Get(string id)
    {
        var ruku = GetById<InvRuKuOutput>(id);
        var mingXiList = await _repMingXi.Queryable.Where(t => t.invRuKuId == id).ToListAsync();

        var list = mingXiList.Adapt<List<InvRuKuMingXiOutput>>();
        var chanPinIdList = list.Select(t => t.chanPinId).ToList();
        var chanPinList = await _basXueYeChanPin.AsQueryable().Where(t => chanPinIdList.Contains(t.Id)).ToListAsync();

        foreach (var item in list)
        {
            var chanPinInfo = chanPinList.FirstOrDefault(t => t.Id == item.chanPinId);
            if (chanPinInfo != null)
            {
                item.pinZhongId = chanPinInfo.pinZhongId;
                item.daLei = chanPinInfo.daLei;
            }
        }
        return new InvRuKuWithMingXiOutput
        {
            master = ruku,
            mingXiList = list
        };
    }

    /// <summary>
    /// 新增成功后返回主键
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<InvRuKu> Add(InvRuKuAddInput input)
    {
        // 1 检查
        var chanPinIdList = input.mingXiList.Select(t => t.chanPinId).ToList();
        var xianXueMaList = input.mingXiList.Select(t => t.xianXueMa).ToList();
        // 获取明细中已存在库存的血液
        var inKuCunList = await _managerKuCun.Queryable.Where(t => xianXueMaList.Contains(t.xianXueMa) && chanPinIdList.Contains(t.chanPinId)).Select(t => t.xianXueMa + t.chanPinId).ToListAsync();
        if (inKuCunList.Count > 0)
        {
            var inKuCunCodeStr = String.Join(", ", inKuCunList);
            throw Oops.Oh("以下血液已存在 , 不能重复入库：" + inKuCunCodeStr);
        }

        // 2 新增
        input.danJuZhuangTai = DanJuZhuangTai.已生效; // 一般情况单击新增后默认已生效

        // 插入主表
        var zhuBiao = AddWithInput(input);

        // 获取产品信息
        var chanPinList = await _basXueYeChanPin.AsQueryable().Where(t => chanPinIdList.Contains(t.Id)).ToListAsync();
        // 插入明细表
        List<InvKuCun> listKuCun = new List<InvKuCun>();
        foreach (var item in input.mingXiList)
        {
            // 添加库存明细
            var kuCun = item.Adapt<InvKuCun>();
            //// 根据产品信息获取品种、大类
            //var chanPinInfo = chanPinList.FirstOrDefault(t => t.Id == kuCun.chanPinId);
            //if (chanPinInfo != null)
            //{
            //    kuCun.pinZhongId = chanPinInfo.pinZhongId;
            //    kuCun.daLei = chanPinInfo.daLei;
            //}
            kuCun.yuanQuId = input.ruKuYuanQuId;
            kuCun.laiYuanId = input.xueYeLaiYuanId;
            kuCun.ruKuShiJian = DateTime.Now;
            kuCun.Id = YitIdHelper.NextId();
            kuCun.kuCunZhuangTai = KuCunZhuangTai.在库;
            listKuCun.Add(kuCun);

            item.Id = YitIdHelper.NextId();//批量插入要提前产生主键
            item.invRuKuId = zhuBiao.Id; // 主表Id
            item.xueYeId = kuCun.Id; // 回写血液Id
        }
        await _repMingXi.InsertRangeAsync(input.mingXiList);
        // 插入库存明细表
        await _managerKuCun.InsertRangeAsync(listKuCun, $"{zhuBiao.danJuLeiXing},单号:{zhuBiao.Id}" );

        return zhuBiao;
    }

    /// <summary>
    /// 更新主表, 修改的情况下:明细需要单独CURD
    /// </summary>
    public bool Update(InvRuKuUpdateInput input)
    {
        // 更新主表
        return UpdateWithInput(input);
    }
}
